package com.teatrace.service.basic.impl;

import java.io.Serializable;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;

import com.teatrace.action.cfg.Basic;
import com.teatrace.commons.util.DaoHelper;
import com.teatrace.commons.util.PageHelper;
import com.teatrace.dao.BaseDao;
import com.teatrace.dao.DaoFactory;
import com.teatrace.dao.template.DaoCallBack;
import com.teatrace.dao.template.DaoTemplate;
import com.teatrace.dao.template.impl.AutoTransactionDaoTemplate;
import com.teatrace.service.basic.BasicService;

public class BasicServiceImpl implements BasicService {

	private DaoTemplate getAutoTransactionDaoTemplate() {
		return new AutoTransactionDaoTemplate();
	}
	


	public void add(final Object obj) throws Exception {
		this.getAutoTransactionDaoTemplate().execute(new DaoCallBack() {
			public Object doInDao(BaseDao dao) throws Exception {
				dao.save(obj);
				return null;
			}
		});
	}

	public void deleteById(final Class clazz, final Serializable id) throws Exception {
		this.getAutoTransactionDaoTemplate().execute(new DaoCallBack() {
			public Object doInDao(BaseDao dao) throws Exception {
				dao.delete(dao.load(clazz, id));
				return null;
			}
		});
	}

	public void deleteByIdArray(final Class clazz, final Serializable[] idArray)
			throws Exception {
		this.getAutoTransactionDaoTemplate().execute(new DaoCallBack() {
			public Object doInDao(BaseDao dao) throws Exception {
				for (Serializable id : idArray) {
					dao.delete(dao.load(clazz, id));
				}
				return null;
			}
		});
	}

	@SuppressWarnings("unchecked")
	public <T> T getById(final Class<T> clazz, final Serializable id) throws Exception {
		return (T) this.getAutoTransactionDaoTemplate().execute(new DaoCallBack() {
			public Object doInDao(BaseDao dao) throws Exception {
				return dao.get(clazz, id);
			}
		});
	}

	public void update(final Object obj) throws Exception {
		this.getAutoTransactionDaoTemplate().execute(new DaoCallBack() {
			public Object doInDao(BaseDao dao) throws Exception {
				dao.update(obj);
				return null;
			}
		});
	}

	public void logicDeleteById(final Class clazz, final Serializable id) throws Exception {
		this.getAutoTransactionDaoTemplate().execute(new DaoCallBack() {
			public Object doInDao(BaseDao dao) throws Exception {
				Object obj = dao.load(clazz, id);
				DaoHelper.setDeleted(clazz, obj, true);
				dao.update(obj);
				return null;
			}
		});
	}

	public void logicDeleteByIdArray(final Class clazz, final Serializable[] idArray)
			throws Exception {
		this.getAutoTransactionDaoTemplate().execute(new DaoCallBack() {
			public Object doInDao(BaseDao dao) throws Exception {
				for (Serializable id : idArray) {
					Object obj = dao.load(clazz, id);
					DaoHelper.setDeleted(clazz, obj, true);
					dao.update(obj);
				}
				return null;
			}
		});
			
	}

	@SuppressWarnings("unchecked")
	public <T> List<T> listByPage(final Class<T> clazz, final int page) throws Exception {
		return (List<T>) this.getAutoTransactionDaoTemplate().execute(new DaoCallBack() {
			public Object doInDao(BaseDao dao) throws Exception {
				return dao.listByPage(clazz, PageHelper.getFirstResult(page, Basic.pageSize), Basic.pageSize);
			}
		});
	}

	@SuppressWarnings("unchecked")
	public <T> List<T> listByCriteria(final Class<T> clazz, final String propertyName,final Object value)
			throws Exception {
		return (List<T>) this.getAutoTransactionDaoTemplate().execute(new DaoCallBack() {
			public Object doInDao(BaseDao dao) throws Exception {
				DetachedCriteria dc = dao.createDetachedCriteria(clazz);
				dc.add(Restrictions.like(propertyName, value));
				return dao.listByCriteria(dc);
			}
		});
	}

	@SuppressWarnings("unchecked")
	public long count(final Class clazz) throws Exception {
		return (Long)this.getAutoTransactionDaoTemplate().execute(new DaoCallBack() {
			public Object doInDao(BaseDao dao) throws Exception {
				return dao.count(clazz);
			}
		});
	}
}